#include "scaleamendcalibration.h"
#include <QDebug>
//#define A 0.001
bool ScaleAmendCalibration::m_firstWeightFlag = false;
static float filterWeight = 0.0;
static float MaxWeight = 0.0;
static float MinWeight = 0.0;
static float SumWeight = 0.0;
static float AvgWeight = 0.0;
static int SampingWeightCount=0;
static int FirstWeightDelay=0;
//20181020 set m_firstWeightFlag as static variable
ScaleAmendCalibration::ScaleAmendCalibration(QThread *parent) :
    QThread(parent),
    m_scaleSourceValue(0.0),
    m_scaleConversionValue(0.0),
    m_unitweight(0.0),
    m_FirstUnitweight(0.0),
    m_calibrationCount(0),
    m_calibrationCountPrevious(0),
    m_latestWeight_temp(0.0),
    MovingAverageWeight(0.0),
    m_conversionWeight(0.0),
    m_deltaWeight(0.0),
    m_filterCoef(0.001),
    m_previousWeight(0.0),
    m_firstWeight_Recalculate_count(0)
{     
    this->start();
}

ScaleAmendCalibration * ScaleAmendCalibration::m_scaleAmendCalibration = NULL;
ScaleAmendCalibration *ScaleAmendCalibration::getobj()
{
    if (m_scaleAmendCalibration == NULL) {
        m_scaleAmendCalibration = new ScaleAmendCalibration();
    }
    return m_scaleAmendCalibration;
}
void ScaleAmendCalibration::run()
{
    msleep(2000);
    while(1) {
        msleep(500);
    }
}

void ScaleAmendCalibration:: getScaleSourceValue(float scaleNewWeight, float unitWeight)
{    
    //Way 1
     //20181017 Chenjiangang update product counting auto calibraiton method
     //20181022 Chenjiangang:if weight is continuously between 0~0.5g, consider scale is empty , clear m_firstWeightFlag to Recalculate first weight
       qDebug() << "~~~~~ scaleNewWeight: " << scaleNewWeight;
       //LowPassWeight = LowPassfilter(m_filterCoef,scaleNewWeight);
          m_latestWeight_temp = LowPassfilter(m_filterCoef,scaleNewWeight);
       // m_latestWeight_temp = scaleNewWeight;
        //m_latestWeight_temp=MovingAverageFilter(20, scaleNewWeight);

       qDebug() << "~~~~~ m_avageWeight_temp: " << m_latestWeight_temp;

      if ( (m_latestWeight_temp >= 0)&& (m_latestWeight_temp <= 0.5))
      {
       m_firstWeight_Recalculate_count++;
      }
      else
      {
       m_firstWeight_Recalculate_count=0;
      }
      if ( m_firstWeight_Recalculate_count >= 5)
      {
       m_firstWeightFlag = false;
       m_firstWeight_Recalculate_count=0;
       m_unitweight = 0;
       m_FirstUnitweight=0;
       m_calibrationCount=0;
      }

      /* 2018.11.17 Chenjiangang change notes
      // 3 types of Tscale scale are  used in G-DIO project
      // £1 Mashwelder : max 30Kg,  min 1g accuracy
      // £2 Mashwelder: max 30Kg,  min 2g accuracy
      // £3 PunchingMachine: max 60Kg,  min 5g accuracy
      */

   // if (!m_firstWeightFlag && (scaleNewWeight > 2)&& (scaleNewWeight < 30000))
      if (!m_firstWeightFlag && (scaleNewWeight >= 1)&& (scaleNewWeight < 60000))
       {
        //m_latestWeight_temp = LowPassfilter(m_filterCoef,scaleNewWeight);

        //m_latestWeight_temp = scaleNewWeight;
        //m_unitweight = MovingAverageFilter(20, scaleNewWeight);
        //MovingAverageWeight=MovingAverageFilter(20, scaleNewWeight);
         //delay 2sec in case of the first part is bouncing in Scale
          FirstWeightDelay++;
           if (FirstWeightDelay>=8) // change count from 20 to 8, which reduce delay from 15secs to ¬6sec
           {
               m_unitweight = scaleNewWeight;
               m_FirstUnitweight = m_unitweight;
               m_previousWeight = m_unitweight;
               m_firstWeightFlag = true;
               //m_calibrationCount++;
               m_calibrationCount=1;
               FirstWeightDelay=0;
           }


       }
    else if (m_firstWeightFlag)
     {
       // m_latestWeight_temp = LowPassfilter(m_filterCoef,m_latestWeight_temp);
        m_deltaWeight=m_latestWeight_temp- m_previousWeight;
        qDebug() << "~~~~~ m_latestWeight_temp: " << m_latestWeight_temp;
        qDebug() << "~~~~~ m_previousWeight: " << m_previousWeight;
        qDebug() << "~~~~~ m_deltaWeight: " << m_deltaWeight;
        m_previousWeight = m_latestWeight_temp;

        // if deltaweight is less than 0.7*unitweight , consider the deltaweight is not stable or NG parts
        // NG parts is NOT added as GOOD parts
     //   if(qAbs(m_deltaWeight)>=(m_unitweight*0.7))
/*
//  Chenjiangang 20181127 add Hysteretic Control to avoid if count oscillation due to small parts or noise
  //      if (m_deltaWeight >= 1){
           if (qAbs(m_deltaWeight)>=(m_unitweight*0.5)) {
              //when single parts weight >50% unitweight , consider this parts +1
              m_calibrationCount = (int)(m_latestWeight_temp / m_unitweight + 0.5);
              //m_calibrationCount = (int)(m_latestWeight_temp / m_unitweight + 0.2);
            }
           //cnsider mall parts or noise
          if ((0.5<=qAbs(m_deltaWeight))&&(qAbs(m_deltaWeight)<=(m_unitweight*0.2))){
               m_calibrationCount = (int)(m_latestWeight_temp / m_unitweight );
           }
          if ((0<=qAbs(m_deltaWeight))&&(qAbs(m_deltaWeight)<=(m_unitweight*0.1))) {
              //when single parts weight >50% unitweight , consider this parts +1
              m_calibrationCount = (int)(m_latestWeight_temp / m_unitweight + 0.5);
              //m_calibrationCount = (int)(m_latestWeight_temp / m_unitweight + 0.2);
            }
*/


        if (m_latestWeight_temp > 0){
               //when single parts weight >50% unitweight , consider this parts +1
             // m_calibrationCount = (int)(m_latestWeight_temp / m_unitweight + 0.5);
               m_calibrationCount = (int)(m_latestWeight_temp / m_unitweight );
            }
         else if (m_deltaWeight < 0)  {
              m_calibrationCount = (int)(m_latestWeight_temp / m_unitweight - 0.5);
              //m_calibrationCount = (int)(m_latestWeight_temp / m_unitweight - 0.2);
            }


        if (m_calibrationCount <=0)    {
            m_calibrationCount  = 0;
         }


         if ((m_latestWeight_temp >= m_unitweight)&& (qAbs(m_latestWeight_temp-m_PreviousWeight_CNTChange)>=(m_unitweight*0.8)))
          //  if ((m_latestWeight_temp >= m_unitweight)&& (qAbs(m_latestWeight_temp-m_PreviousWeight_CNTChange)>=(m_FirstUnitweight*0.8)))
            {
            //m_unitweight = m_latestWeight_temp / m_calibrationCount;
            //m_unitweight=m_FirstUnitweight;
            //UnitsWeight_Change_Flag=ture;
            qDebug() << "~~~~~ qAbs(m_latestWeight_temp-m_PreviousWeight_CNTChange): " << qAbs(m_latestWeight_temp-m_PreviousWeight_CNTChange);

        }

     //20181024,meet calibraited m_unitweight  compensate according to T-Scale condition!
        if(unitWeight>=1)
          {
            if ((qAbs(m_calibrationCount-(int)(m_latestWeight_temp/unitWeight))>=5))
            {
              m_unitweight=unitWeight;
              qDebug() << "~~~~~ meet calibraited m_unitweight  compensate according to T-Scale condition! "<<m_unitweight;
            }
          }
        else if(( 1<=m_calibrationCount)&&(m_calibrationCount<20))
          {
             m_unitweight=m_FirstUnitweight;
          }

        else if( m_calibrationCount>=20)
          {
             float ScaleCoef_Bigdata=1.044; //  1044/1000

              m_unitweight=m_FirstUnitweight*ScaleCoef_Bigdata;
              qDebug() << "~~~~~ ScaleCoef_Bigdata: " <<ScaleCoef_Bigdata;
          }


  }
      if (m_calibrationCount!=m_calibrationCountPrevious)
      {
           //CalibrationCountChange_log++;
           m_PreviousWeight_CNTChange=m_latestWeight_temp;
           m_calibrationCountPrevious=m_calibrationCount;
            qDebug() << "~~~~~ m_PreviousWeight_CNTChange: " <<m_PreviousWeight_CNTChange;
            qDebug() << "~~~~~ m_calibrationCount: " <<m_calibrationCount;
            qDebug() << "~~~~~ m_calibrationCountPrevious: " <<m_calibrationCountPrevious;


      }


     //mStandardPara->calibrationCount = m_calibrationCount;
     emit sendCalibrationCount(m_calibrationCount,m_unitweight);

          //  emit showscale_unitWeight(mStandardPara->calibrationCount);

    //Way  2
    /*if (unitWeight > 0.5) {
        if (scaleSourceValue > 0)
        {
            m_calibrationCount = (int)(scaleSourceValue / unitWeight + 0.5);
        }
        else if (scaleSourceValue < 0) {
            m_calibrationCount = (int)(scaleSourceValue / unitWeight - 0.5);
        }
        emit sendCalibrationCount(m_calibrationCount);
    }*/

}

void ScaleAmendCalibration::getScaleUw(float uw)
{
    m_unitweight = uw;
}

void ScaleAmendCalibration::filter(float &adoutValue,float &sourceWeight)
{
    int i = 0;
    char count;
    float sum = 0.0;
    value_buff[i++] = sourceWeight;

    if (i == SAMPLE_MAX_SIZE) {
        i = 0;
    }

    for (count = 0; count < SAMPLE_MAX_SIZE; count++) {
        sum += value_buff[(int)count];
        adoutValue = (float)(sum/SAMPLE_MAX_SIZE);
    }
}

// 20181018,chenjiangang, low pass filter design
// Cut_off_frequency =fs*K/2pi , baud rate 4800kps
//For example:Cut_off_frequency=0.001*4800Hz/2pi=0.764hz
float ScaleAmendCalibration::LowPassfilter(float filterScale, float newWeight)
{
    //float filterWeight = 0.0;
    filterWeight = filterScale*filterWeight + (1-filterScale)*newWeight;
    return filterWeight;//
}

float ScaleAmendCalibration::MovingAverageFilter(int SampingNum, float SampingWeight)
{
 /* float MaxWeight = 0.0;
    float MinWeight = 0.0;
    float SumWeight = 0.0;
    float AvgWeight = 0.0;
    int SampingWeightCount=0;
*/
    if(SampingWeight>=MaxWeight)
    {
        MaxWeight=SampingWeight;
        qDebug() << "~~~~~ MaxWeight: " << MaxWeight;
    }
    if(SampingWeight<=MinWeight)
    {
        MinWeight=SampingWeight;
    }

    SumWeight=SumWeight+SampingWeight;
    qDebug() << "~~~~~ SumWeight: " << SumWeight;
    SampingWeightCount=SampingWeightCount+1;
    qDebug() << "~~~~~ SampingWeightCount: " << SampingWeightCount;
     qDebug() << "~~~~~ SampingNum: " << SampingNum;
   for(int i=0;i<SampingNum;i++)
   {
       if(SampingWeight>=MaxWeight)
       {
           MaxWeight=SampingWeight;
           qDebug() << "~~~~~ MaxWeight: " << MaxWeight;
       }
   }
     if(SampingWeightCount>=SampingNum)
    {

        qDebug() << "~~~~~ EnterenceInside: " << " SampingWeightCount>=SampingNum";

        if(SampingWeightCount<3)
           {
            SampingWeightCount=3;
           }
        AvgWeight=(SumWeight-MaxWeight-MinWeight)/(SampingWeightCount-2);
        qDebug() << "~~~~~ AvgWeight: " << AvgWeight;

       MaxWeight=0;
       MinWeight=0;
       SumWeight=0;
       SampingWeightCount=0;
    }


   return AvgWeight;//

}

